//
//  UIImagePickerController+Rx.swift
//  live
//
//  Created by melvyn on 2018/8/23.
//  Copyright © 2018 NEET. All rights reserved.
//

import UIKit
import RxSwift
import RxCocoa

typealias ImagePickerControllerDelegate = UINavigationControllerDelegate & UIImagePickerControllerDelegate

extension Reactive where Base: UIImagePickerController {
    
    var _delegate: DelegateProxy<UIImagePickerController, ImagePickerControllerDelegate> {
        return RxImagePickerDelegateProxy.proxy(for: base)
    }
    
    /**
     Reactive wrapper for `delegate` message.
     */
    public var didFinishPickingMediaWithInfo: Observable<[UIImagePickerController.InfoKey : Any]> {
        return _delegate
            .methodInvoked(#selector(UIImagePickerControllerDelegate.imagePickerController(_:didFinishPickingMediaWithInfo:)))
            .map({ (a) in
                return a[1] as! [UIImagePickerController.InfoKey : Any]
            })
    }
    
    /**
     Reactive wrapper for `delegate` message.
     */
    public var didCancel: Observable<()> {
        return _delegate
            .methodInvoked(#selector(UIImagePickerControllerDelegate.imagePickerControllerDidCancel(_:)))
            .map {_ in () }
    }
    
}

extension Reactive where Base: UIImagePickerController {
    
    static func present(by parent: UIViewController?, animated: Bool = true, configuration: @escaping (UIImagePickerController) throws -> () = { x in }) -> Observable<UIImagePickerController> {
        return Observable.create { [weak parent] observer in
            let imagePicker = UIImagePickerController()
            let dismissDisposable = imagePicker.rx
                .didCancel
                .subscribe(onNext: { [weak imagePicker] _ in
                    imagePicker?.dismiss(animated: animated, completion: nil)
                })
            
            do {
                try configuration(imagePicker)
            } catch let error {
                observer.on(.error(error))
                return Disposables.create()
            }
            
            guard let parent = parent else {
                observer.on(.completed)
                return Disposables.create()
            }
            
            parent.present(imagePicker, animated: animated, completion: nil)
            observer.on(.next(imagePicker))
            
            return Disposables.create(dismissDisposable, Disposables.create {
                imagePicker.dismiss(animated: animated, completion: nil)
            })
        }
    }
}
